﻿using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace EYangFramework.Common.AutoMapper
{
    public class AutoMapHelper
    {
        public void AutoMapInit(Type type)
        {
            AutoMapAttribute autoMap = type.GetCustomAttributes(typeof(AutoMapAttribute), false)[0] as AutoMapAttribute;
            Type sourceType = autoMap.SourceType;
            Type targetType = autoMap.TargetType;
            if (sourceType != null && targetType == null)
            {
                if (sourceType == type)
                {
                    throw new AutoMapException($"{type}类型指定的原始映射类型与自身相同,但未指定目标类型!");
                }
                Mapper.Initialize(t => t.CreateMap(sourceType, type));
            }
            else if (sourceType == null && targetType != null)
            {
                if (targetType == type)
                {
                    throw new AutoMapException($"{type}类型指定的目标映射类型与自身相同,但未指定原始类型!");
                }
                Mapper.Initialize(t => t.CreateMap(type, targetType));
            }
            else if (sourceType != null && targetType != null)
            {
                if (sourceType != type && targetType != type)
                {
                    throw new AutoMapException($"{type}指定的映射类型与自身无关,这是不允许,同时无意义的操作,会给后期维护带来意想不到的困难!请前往调整!");
                }
                if (sourceType == targetType)
                {
                    throw new AutoMapException($"{type}指定的原映射类型与目标类型相同,这是一个无效的映射,请前往调整!");
                }
                //实现双向绑定
                Mapper.Initialize(t => t.CreateMap(sourceType, targetType));
                Mapper.Initialize(t => t.CreateMap(targetType, sourceType));
            }
            else
            {
                throw new AutoMapException($"{type}的映射关系类型为空,无法完成映射,这是一个无意义的映射!");
            }
        }
        public void AutoMapInit(Assembly asmCurrent)
        {
            Type[] types = asmCurrent.GetTypes().Where(t => t.IsPublic && !t.IsInterface && !t.IsAbstract && !t.IsGenericType).ToArray();
            foreach (Type current in types)
            {
                if (current.GetCustomAttributes().Any(t => t is AutoMapAttribute))
                {
                    this.AutoMapInit(current);
                }
            }
        }
        /// <summary>
        /// 自定义映射关系,用于非自定义的复杂映射
        /// </summary>
        /// <param name="config"></param>
        public void CustomCreateMap(Action<IMapperConfigurationExpression> config)
        {
            Mapper.Initialize(config);
        }
        /// <summary>
        /// 根据原始实体获取到对应的目标类型的实体
        /// </summary>
        /// <typeparam name="TTarget"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public TTarget GetTarget<TTarget>(object source)
        {
            return Mapper.Map<TTarget>(source);
        }
    }
}
